//
//  MapViewController.m
//  WLTagent
//
//  Created by Sergei Sevriugin on 8/13/09.
//  Copyright 2009 Bellwood Systems. All rights reserved.
//

#import "MapViewController.h"

#define	MAX_SPAN_DELTA			0.02
#define	DEFAULT_SPAN_DELTA		0.01
#define DEFAULT_SPAN_FACTOR		2
#define	DEFAULT_CENTER_LAT		55.910507
#define DEFAULT_CENTER_LON		37.399982
#define MIN_DISTANCE			100
#define MAX_HOP_DISTANCE		1500
#define MIN_HOP_DISTANCE		100
#define MAX_ACCURACY			1000
#define MEASURMENT_COUNT_IDLE	2


@implementation MapViewController

@synthesize gmaps;
@synthesize currentMapId;
@synthesize loaded;

#pragma mark -
#pragma mark View Data management

- (void) loadAnnotations {
	MKMapView*				mapView				= (MKMapView *) [self view];		
	NSInteger				countOfFeatures		= [gmaps countOfFeaturesOfMap:currentMapId];
	GDataEntryMapFeature*	feature				= nil;
	ITAnnotation*			annotation			= nil;
		
	for (int i = 0; i < countOfFeatures; i++ ) {
		
		feature				= [gmaps getFeatureOfMap:currentMapId AtIndex:i];
		annotation			= [[[ITAnnotation alloc] initWithMapFeature:feature] autorelease];
		
		[annotation setMapViewController:self];
		[annotation putOnMap];		
	}
	
	[mapView setShowsUserLocation:YES];
	
	annotations				= [[NSMutableArray alloc] initWithCapacity:3];
	
	[self setLoaded:YES];
}

- (void) waitForData {
	UIViewController *indicatorViewController = [[UIViewController alloc] initWithNibName:@"IndicatorView" bundle:nil];
	[self presentModalViewController:indicatorViewController animated:YES];
	[indicatorViewController release];
}

- (void) stopWaitForData {
	if (loaded == NO) {
		[self loadAnnotations];
	}
	[self dismissModalViewControllerAnimated:YES];
}

- (void) loadData {
	if (loaded == NO) {
		[self loadAnnotations];
	}
}

 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
		[self setLoaded:NO];
		
		annotations			= nil;
		recordLocations		= NO;
		
		firstLocation		= YES;
		lastSavedAnnotation = -1;
    }
    return self;
}

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
	
	if (gmaps) { 
		// set FeaturesView property
		[gmaps setActiveView:self];
		
		if (currentMapId >= 0 && currentMapId < [gmaps countOfMaps]) {
			// fetch current map features
			[gmaps fetchFeaturesOfMapById:currentMapId];
		}
	}
}
*/

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
	
	if (gmaps) { 
		// set FeaturesView property
		[gmaps setActiveView:self];
		
		if (currentMapId >= 0 && currentMapId < [gmaps countOfMaps]) {
			// fetch current map features
			[gmaps fetchFeaturesOfMap:currentMapId];
		}
	}	
}

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}
/*
- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;	
}
*/

- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error {
	if (error) {
		NSString* titleString		= @"Map Load Error";
		NSString* messageString		= [error localizedDescription];		
		NSString* moreString		= [error localizedFailureReason] ? [error localizedFailureReason] :
												NSLocalizedString(@"Try it again later.", nil);
		
		messageString				= [NSString stringWithFormat:@"%@. %@", messageString, moreString];
		
		UIAlertView* alertView		= [[UIAlertView alloc] initWithTitle:titleString
													message:messageString 
													delegate:self
													cancelButtonTitle:@"Cancel" 
													otherButtonTitles:nil];
		[alertView show];
		[alertView release];
		
		NSLog(@"iTrack: Map Load Error, %@", error);
	}		
}

- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
	if (error) {
		NSString* titleString		= @"User Locate Error";
		NSString* messageString		= [error localizedDescription];		
		NSString* moreString		= [error localizedFailureReason] ? [error localizedFailureReason] :
												NSLocalizedString(@"Try it again later.", nil);
		
		messageString				= [NSString stringWithFormat:@"%@. %@", messageString, moreString];
		
		UIAlertView* alertView		= [[UIAlertView alloc] initWithTitle:titleString
											message:messageString 
											delegate:self
											cancelButtonTitle:@"Cancel" 
											otherButtonTitles:nil];
		[alertView show];
		[alertView release];
		
		NSLog(@"iTrack: User Locate Error, %@", error);
	}	
}

- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView {
}

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
	CLLocation*			user_loc	= [userLocation location];
	
	if (user_loc == nil || annotations == nil) {
		return;
	}
	
	if (firstLocation) {
		firstLocation = NO;
		
		MKCoordinateRegion		reg;
		MKCoordinateSpan		span;
		
		span.latitudeDelta		= DEFAULT_SPAN_DELTA;
		span.longitudeDelta		= DEFAULT_SPAN_DELTA;
		
		reg.center				= [user_loc coordinate];
		reg.span				= span;
		
		[mapView setRegion:reg animated:YES];
	}
	
	if (recordLocations == NO) {
		return;
	}

	NSInteger			ann_count	= [annotations count];
	
	if (ann_count < 3) {
		return;
	}
	[[annotations objectAtIndex:ann_count-1] updateLocation:user_loc];
	[[annotations objectAtIndex:ann_count-2] addLocation:user_loc];
}

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
	return nil;
}

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
	if ([overlay isKindOfClass:[ITAnnotation class]])
	{
		ITAnnotation*			annotation		= (ITAnnotation*) overlay;
		
		if ([annotation kind] == ITAnnotationKindInvalid || [annotation kind] == ITAnnotationKindPoint) {
			return nil;
		}
		
		NSArray*				locations		= [annotation locations];
		NSInteger				locationsCount	= [locations count];		
		CLLocationCoordinate2D* coords			= malloc(sizeof(CLLocationCoordinate2D) * locationsCount);
		
		if (coords == nil) {
			return nil;
		}
		
		for (int i = 0; i < locationsCount; i++) {
			coords[i] = [[locations objectAtIndex:i] coordinate];
		}
		
		MKPolyline*				annotation_line	= [MKPolyline polylineWithCoordinates:coords count:locationsCount];
		MKPolylineView*			annotationView	= [[[MKPolylineView alloc] initWithPolyline:annotation_line] autorelease];

		if (annotationView) {
			annotationView.fillColor			= [[UIColor cyanColor] colorWithAlphaComponent:0.2];
			annotationView.strokeColor			= [[UIColor blueColor] colorWithAlphaComponent:0.7];
			annotationView.lineWidth			= 3;
		}
		
		free(coords);
		
		return annotationView;
	}
	return nil;
}


-(IBAction)myShowDetailsMethod:(id)sender {
}

- (void) startRecLocations {
	MKMapView*		mapView		= (MKMapView *) [self view];
	
	if (mapView == nil || annotations == nil) {
		return;
	}
	
	CLLocation*		user_loc	= [[mapView userLocation] location];
	
	if ([mapView isUserLocationVisible] == NO || user_loc == nil) {
		return;
	}
		
	ITAnnotation*	ann_start	= [[[ITAnnotation alloc] initWithLocation:user_loc andTitle:@"Start Location"] autorelease];
	ITAnnotation*	ann_path	= [[[ITAnnotation alloc] initWithLocation:user_loc andTitle:@"Path"] autorelease];
	ITAnnotation*	ann_loc		= [[[ITAnnotation alloc] initWithLocation:user_loc andTitle:@"Final Location"] autorelease];
	
	if (ann_start)	[annotations addObject:ann_start];
	if (ann_path)	[annotations addObject:ann_path];
	if (ann_loc)	[annotations addObject:ann_loc];
	
	recordLocations = YES;
}

- (void) stopRecLocations {
	recordLocations = NO;
}

- (IBAction)recClicked:(id)sender {
	NSArray*			items		= [self toolbarItems];
	
	UIBarButtonItem*	recItem		= [items objectAtIndex:0];
	UIBarButtonItem*	pauseItem	= [items objectAtIndex:1];
	UIBarButtonItem*	addItem		= [items objectAtIndex:2];	

	[self startRecLocations];

	if (recordLocations == YES) {
		recItem.enabled				= NO;
		pauseItem.enabled			= YES;
		addItem.enabled				= NO;
		
	}	
}

- (IBAction)pauseClicked:(id)sender {
	NSArray*			items		= [self toolbarItems];
	
	UIBarButtonItem*	recItem		= [items objectAtIndex:0];
	UIBarButtonItem*	pauseItem	= [items objectAtIndex:1];
	UIBarButtonItem*	addItem		= [items objectAtIndex:2];	

	[self stopRecLocations];
	
	if (recordLocations == NO) {
		recItem.enabled				= YES;
		pauseItem.enabled			= NO;
		addItem.enabled				= YES;
	}
}

-(IBAction)addClicked:(id)sender {
	if (annotations == nil || [annotations count] - 1 == lastSavedAnnotation) {
				
		UIAlertView* alertView			= [[UIAlertView alloc] initWithTitle:@"Nothing to save"
											message:@"Record locations first." 
											delegate:self
											cancelButtonTitle:@"Cancel" 
											otherButtonTitles:nil];
		[alertView show];
		[alertView release];
		
		return;
	}
	
	[gmaps setCurrentMap:currentMapId];
	
	NSInteger			ann_count	= [annotations count];
	BOOL				needToSave	= NO;
	
	for (int i = ann_count - 1; i > lastSavedAnnotation; i = i - 3) {
		ITAnnotation*	ann_start	= [annotations objectAtIndex:i-2];
		ITAnnotation*	ann_path	= [annotations objectAtIndex:i-1];
		ITAnnotation*	ann_loc		= [annotations objectAtIndex:i];
		
		if (ann_start) {
			// check if path is real line not a single point
			if ([ann_start isPoint] && [ann_path isPath]) {
				[ann_start saveFeature];
				[gmaps addCurrentMapFeature:[ann_start feature]];
				
				[ann_start setMapViewController:self];
				[ann_start putOnMap];
				
				needToSave			= YES;
			}
		}
		
		if (ann_path) {
			// check if path is real line not a single point
			if ([ann_path isPath]) {
				[ann_path saveFeature];
				[gmaps addCurrentMapFeature:[ann_path feature]];
				
				[ann_path setMapViewController:self];
				[ann_path putOnMap];
				
				needToSave			= YES;
			}
		}
		
		if (ann_loc) {
			// check if final location is point
			if ([ann_loc isPoint]) {
				[ann_loc saveFeature];
				[gmaps addCurrentMapFeature:[ann_loc feature]];
				
				[ann_loc setMapViewController:self];
				[ann_loc putOnMap];
				
				needToSave			= YES;
			}
		}
	}
	
	if (needToSave) {
		[gmaps setActiveView:self];
		[gmaps saveCurrentMapFeatures];
		[gmaps setCurrentMapFeaturesLoaded:NO];
		
		lastSavedAnnotation				= ann_count - 1;
		
		NSArray*			items		= [self toolbarItems];
		
		UIBarButtonItem*	recItem		= [items objectAtIndex:0];
		UIBarButtonItem*	pauseItem	= [items objectAtIndex:1];
		UIBarButtonItem*	addItem		= [items objectAtIndex:2];		

		recItem.enabled					= YES;
		pauseItem.enabled				= NO;
		addItem.enabled					= NO;
	}
}

- (void)dealloc {
	
	[annotations release];
    [super dealloc];
}

@end
